# uamcf/adapters/base.py
from abc import ABC, abstractmethod
from typing import Dict, Any, Optional, List, Tuple, Union

from ..utils.logger import get_logger


class ModelAdapter(ABC):
    """
    模型适配器基类，为不同深度学习框架提供统一接口
    """

    def __init__(self):
        """初始化适配器"""
        self.logger = get_logger(self.__class__.__name__)

    @abstractmethod
    def load_model(self, model_path: str) -> Any:
        """
        加载模型

        Args:
            model_path: 模型文件路径

        Returns:
            加载的模型
        """
        pass

    @abstractmethod
    def save_model(self, model: Any, save_path: str) -> str:
        """
        保存模型

        Args:
            model: 要保存的模型
            save_path: 保存路径

        Returns:
            实际保存的路径
        """
        pass

    @abstractmethod
    def get_model_info(self, model: Any) -> Dict:
        """
        获取模型基本信息

        Args:
            model: 模型

        Returns:
            模型信息字典
        """
        pass

    @abstractmethod
    def get_layers_info(self, model: Any) -> Dict[str, Dict]:
        """
        获取模型的层信息

        Args:
            model: 模型

        Returns:
            层信息字典，键为层名称，值为层属性
        """
        pass

    @abstractmethod
    def get_layer(self, model: Any, layer_name: str) -> Any:
        """
        获取指定名称的层

        Args:
            model: 模型
            layer_name: 层名称

        Returns:
            层对象
        """
        pass

    @abstractmethod
    def replace_layer(self, model: Any, layer_name: str, new_layer: Any) -> bool:
        """
        替换模型中的层

        Args:
            model: 模型
            layer_name: 层名称
            new_layer: 新层

        Returns:
            是否成功替换
        """
        pass

    @abstractmethod
    def generate_sample_input(self, model: Any) -> Any:
        """
        为模型生成示例输入

        Args:
            model: 模型

        Returns:
            示例输入
        """
        pass

    @abstractmethod
    def measure_inference_time(self, model: Any, input_data: Any, num_runs: int = 10) -> float:
        """
        测量模型推理时间

        Args:
            model: 模型
            input_data: 输入数据
            num_runs: 运行次数

        Returns:
            平均推理时间（毫秒）
        """
        pass

    @abstractmethod
    def measure_memory_usage(self, model: Any, input_data: Any = None) -> float:
        """
        测量模型内存使用

        Args:
            model: 模型
            input_data: 输入数据

        Returns:
            内存用量（MB）
        """
        pass

    @abstractmethod
    def evaluate_accuracy(self, model: Any, eval_data: Any) -> float:
        """
        评估模型准确率

        Args:
            model: 模型
            eval_data: 评估数据

        Returns:
            准确率
        """
        pass

    @abstractmethod
    def fine_tune(self, model: Any, train_data: Any, iterations: int = 5,
                  early_stopping: bool = True) -> Any:
        """
        微调模型

        Args:
            model: 模型
            train_data: 训练数据
            iterations: 训练迭代次数
            early_stopping: 是否使用早停

        Returns:
            微调后的模型
        """
        pass

    @abstractmethod
    def get_model_size(self, model: Any) -> int:
        """
        获取模型大小（字节）

        Args:
            model: 模型

        Returns:
            模型大小（字节）
        """
        pass

    @abstractmethod
    def get_parameter_count(self, model: Any) -> int:
        """
        获取模型参数数量

        Args:
            model: 模型

        Returns:
            参数数量
        """
        pass

    @abstractmethod
    def measure_layer_latency(self, model: Any, sample_input: Any) -> Dict[str, float]:
        """
        测量模型各层的延迟

        Args:
            model: 模型
            sample_input: 样本输入

        Returns:
            各层延迟字典
        """
        pass

    @abstractmethod
    def clone_model(self, model: Any) -> Any:
        """
        克隆模型

        Args:
            model: 原始模型

        Returns:
            克隆后的模型
        """
        pass

    @abstractmethod
    def export_model(self, model: Any, output_path: str, format: str = "native") -> str:
        """
        导出模型到指定格式

        Args:
            model: 模型
            output_path: 输出路径
            format: 导出格式

        Returns:
            导出文件路径
        """
        pass